#pragma once

#include <thread>
#include <mutex>
#include <condition_variable>
#include <unordered_map>
#include <string>


namespace DB
{

class Context;


/** Periodically (each minute, starting at 30 seconds offset)
  *  calculates and updates some metrics,
  *  that are not updated automatically (so, need to be asynchronously calculated).
  */
class AsynchronousMetrics
{
public:
	AsynchronousMetrics(Context & context_)
		: context(context_), thread([this] { run(); })
	{
	}

	~AsynchronousMetrics();

	using Value = double;
	using Container = std::unordered_map<std::string, Value>;

	/// Returns copy of all values.
	Container getValues() const;

private:
	Context & context;

	bool quit {false};
	std::mutex wait_mutex;
	std::condition_variable wait_cond;

	Container container;
	mutable std::mutex container_mutex;

	std::thread thread;

	void run();
	void update();

	void set(const std::string & name, Value value);
};

}
